using UnityEngine;
using System.Collections;

/**
 * Script of result displaying behaviour description.
 * The purpose of this class is to display the result of the game.
 * @author Benjamin Bruneau
 */
public class ResultScript : MonoBehaviour 
{
	
	private const int TIMEMAXLENGTH = 11; //Time string maxlength
	private const int LEVEL_COUNT = 9; // Level count
	
	private const string END_GAME = "End"; // End Game
	private const string DATA_CONTAINER_NAME = "Result"; // Data Container GameObject's name
	private const string SAVE_MANAGER_NAME = "SaveManager"; // Save Manager GameObject's name
	private const string NEXT_LEVEL = "Next Level"; // Next Level text
	private const string SELECTED_NEXT_LEVEL = "[ Next Level ]"; // Selected Next level text
	private const string END_OF_REPLAY = "End of Replay !"; // End of replay text
	private const string GAME_OVER = "Game Over ! Try again ?"; // Game over text
	private const string GAME_WON = "Congratulations ! Time : "; // Game won text
	private const string NEW_RECORD = "New Record ! Time : "; // New Record text
	private const string PREFIX = "LevelScene"; // Level prefix name
	private const string BRONZE = "bronze"; // Bronze Reward
	private const string SILVER = "silver"; // Silver Reward
	private const string GOLD = "gold"; // Gold Reward
	
	private GameObject _dataContainer; // Data container GameObject
	private GameObject _saveManager; // Save manager GameObject
	
	private bool _isNewHighScore = false; // Is new high score
	
	public GameObject _retryText; // Retry Text GameObject
	public GameObject _replayText; // Replay Text GameObject
	public GameObject _nextLevelText; // Next Level Text GameObject
	public GameObject _returnToMenuText; // Return to Menu Text GameObject
	public GameObject _selectableTexts; // Selectable Texts GameObject
	public GameObject _gold; // Gold medal GameObject
	public GameObject _silver; // Silver medal GameObject
	public GameObject _bronze; // Bronze medal GameObject
	
	/**
	 * Called on initialization.
	 * @return void
	 */
	void Start () 
	{
		
		//Initialized because these objects move through scenes
		_dataContainer = GameObject.Find (DATA_CONTAINER_NAME);
		_saveManager = GameObject.Find (SAVE_MANAGER_NAME);
		manageRetry();
		
		//If win
		if (_dataContainer.GetComponent<TimeScript>().getWin())
		{
			// Display and link next level
			if(!_dataContainer.GetComponent<DataContainerScript>()._nextLevel.Equals(END_GAME))
			{
				displayNextLevel();
			}
			
			if (!_dataContainer.GetComponent<TimeScript>()._isReplayMode)
			{
				// Display time
			displayTime ();
			}  else {
				// If replay
				this.gameObject.GetComponent<TextMesh>().text = END_OF_REPLAY;
				
			}
			
		// Lose
		} else {
			
			if(isNextLevelUnlocked())
			{
				displayNextLevel();
			}
			
			if (!_dataContainer.GetComponent<TimeScript>()._isReplayMode)
			{
				// Game Over
				this.gameObject.GetComponent<TextMesh>().text = GAME_OVER;
			}  else {
				
				// If replay
				this.gameObject.GetComponent<TextMesh>().text = END_OF_REPLAY;
				
			}
		}
		
		displayMedal();
		
	}
	
	/**
	 * Retry direction manager.
	 * @return void
	 */
	private void manageRetry ()
	{
		
		string currentLevel = _dataContainer.GetComponent<DataContainerScript>()._currentLevel;
		_retryText.GetComponent<DetectClickOnObjectScript>()._forward = currentLevel;
		_replayText.GetComponent<DetectClickOnObjectScript>()._forward = currentLevel;
	}
	
	/**
	 * Display Next level Button manager.
	 * @return void
	 */
	private void displayNextLevel ()
	{
		// Change texts and enable Next Level Button
		string nextLevel = _dataContainer.GetComponent<DataContainerScript>()._nextLevel;
		
		_selectableTexts.GetComponent<MenuControllerScript>()._selectedChild = _nextLevelText;
		
		_nextLevelText.GetComponent<TextMesh>().text = NEXT_LEVEL;
		_nextLevelText.GetComponent<BoxCollider>().enabled = true;
		_nextLevelText.GetComponent<DetectClickOnObjectScript>()._forward = nextLevel;
		_nextLevelText.GetComponent<DetectClickOnObjectScript>()._textOriginal = NEXT_LEVEL;
		_nextLevelText.GetComponent<DetectClickOnObjectScript>()._textSelected = SELECTED_NEXT_LEVEL;
		_nextLevelText.GetComponent<DetectClickOnObjectScript>()._selected = true;
		
		_retryText.GetComponent<DetectClickOnObjectScript>()._selected = false;
		_retryText.GetComponent<DetectClickOnObjectScript>()._top = _nextLevelText;
		
		_returnToMenuText.GetComponent<DetectClickOnObjectScript>()._bottom = _nextLevelText;	
	}
	
	/**
	 * Gets previous high score.
	 * @return float
	 */
	private void displayMedal()
	{
		int levelNumber = int.Parse(_dataContainer.GetComponent<DataContainerScript>()._currentLevel.Replace(PREFIX,""));
		string medal = (((ArrayList)_saveManager.GetComponent<SaveManagerScript>()._sequence[levelNumber-1])[3]).ToString();
		
		switch (medal) 
		{
			case	 GOLD : _gold.GetComponent<MeshRenderer>().enabled = true;
				break;
			case	 SILVER : _silver.GetComponent<MeshRenderer>().enabled = true;
				break;
			case	 BRONZE : _bronze.GetComponent<MeshRenderer>().enabled = true;
				break;
			default:
				break;
		}
		
	}
	
	/**
	 * Gets previous high score.
	 * @return float
	 */
	private float getHighScore()
	{
		int levelNumber = int.Parse(_dataContainer.GetComponent<DataContainerScript>()._currentLevel.Replace(PREFIX,""));
		float previousHighScore = float.Parse((((ArrayList)_saveManager.GetComponent<SaveManagerScript>()._sequence[levelNumber-1])[2]).ToString());
		return previousHighScore;
	}
	
	/**
	 * Sets previous high score.
	 * @param float
	 * @return void
	 */
	private bool isNextLevelUnlocked()
	{
		int levelNumber = int.Parse(_dataContainer.GetComponent<DataContainerScript>()._currentLevel.Replace(PREFIX,""));
		bool unlocked = false;
		if(levelNumber != LEVEL_COUNT) 
		{
			unlocked = bool.Parse((((ArrayList)_saveManager.GetComponent<SaveManagerScript>()._sequence[levelNumber])[1]).ToString());
		}
		
			
		return unlocked;
	}
	
	/**
	 * Sets previous high score.
	 * @param float
	 * @return void
	 */
	private void setHighScore(float pNewHighScore)
	{
		int levelNumber = int.Parse(_dataContainer.GetComponent<DataContainerScript>()._currentLevel.Replace(PREFIX,""));
		
		//Unlock next level
		if(levelNumber != LEVEL_COUNT) 
		{
			((ArrayList)_saveManager.GetComponent<SaveManagerScript>()._sequence[levelNumber])[1] = true;
		}
		
		((ArrayList)_saveManager.GetComponent<SaveManagerScript>()._sequence[levelNumber-1])[2] = pNewHighScore;
			
		if(pNewHighScore < _dataContainer.GetComponent<DataContainerScript>()._goldTime)
		{
			((ArrayList)_saveManager.GetComponent<SaveManagerScript>()._sequence[levelNumber-1])[3] = GOLD;
		} else {
			if(pNewHighScore < _dataContainer.GetComponent<DataContainerScript>()._silverTime)
			{
				((ArrayList)_saveManager.GetComponent<SaveManagerScript>()._sequence[levelNumber-1])[3] = SILVER;
			} else {
				if(pNewHighScore < _dataContainer.GetComponent<DataContainerScript>()._bronzeTime)
				{
					((ArrayList)_saveManager.GetComponent<SaveManagerScript>()._sequence[levelNumber-1])[3] = BRONZE;
				}
			}
		}
		
		// Flush in file
		_saveManager.GetComponent<SaveManagerScript>().saveInFile();
		
	}
	
	/**
	 * Display result and time text manager.
	 * @return void
	 */
	private void displayTime ()
	{
		
		// Gets previous high score
		float previousHighScore = getHighScore();
		
		//Get final timer
		float time = _dataContainer.GetComponent<TimeScript>().getTime();
			
		// Is new high score ?
		if(time < previousHighScore)
		{
			_isNewHighScore = true;
			setHighScore(time);		
		}
		
		//Format it
		string tempTimeString = System.TimeSpan.FromSeconds(time).ToString();
		string timeString;
		if (tempTimeString.Length < TIMEMAXLENGTH)
		{
			timeString = tempTimeString.Substring(3);
		} else {
			timeString = tempTimeString.Substring(3,8);
		}
		
		//Display
		if(_isNewHighScore)
		{
			this.gameObject.GetComponent<TextMesh>().text = NEW_RECORD + timeString + ".";
		} else {
			this.gameObject.GetComponent<TextMesh>().text = GAME_WON + timeString + ".";
		}

	}
}
